package org.mozhu.mboot.admin.maintain.email.service;

import com.google.common.collect.Maps;
import org.joda.time.LocalDateTime;
import org.mozhu.mboot.admin.GlobalSettings;
import org.mozhu.mboot.admin.maintain.email.entity.EmailValidation;
import org.mozhu.mboot.admin.maintain.email.repository.EmailValidationRepository;
import org.mozhu.mboot.admin.system.account.entity.User;
import org.mozhu.mboot.admin.system.account.service.UserService;
import org.mozhu.mboot.core.data.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.UUID;

/**
 * 邮箱验证 - 业务层实现类
 * 
 * @author ZhangPei
 */
@Transactional
@Service
public class EmailValidationServiceImpl extends BaseService<EmailValidation, Long> implements EmailValidationService {

	private static final String SYSTEM_EMAIL_VALIDATION_PREFIX = "system.email.validation.";
	@Autowired
	EmailService emailService;

	@Autowired
	UserService userService;

	@Autowired
	GlobalSettings globalSettings;

	protected EmailValidationRepository getBaseRepository() {
		return (EmailValidationRepository) baseRepository;
	}

	@Override
	public EmailValidation findByEmailAndType(String email, String type) {
		return this.getBaseRepository().findByEmailAndType(email, type);
	}

	@Override
	public EmailValidation findByCodeAndType(String code, String type) {
		return this.getBaseRepository().findByCodeAndType(code, type);
	}

	@Override
	public void sendVerifyCode(String email, String type) {
		EmailValidation emailValidation = this.findByEmailAndType(email, type);
		if (emailValidation == null) {
			emailValidation = new EmailValidation();
			emailValidation.setEmail(email);
			emailValidation.setType(type);
			String verifyCode = generateVerifyCode(email, type);
			emailValidation.setCode(verifyCode);
		} else if (emailValidation.isExpired()) {
			String verifyCode = generateVerifyCode(email, type);
			emailValidation.setCode(verifyCode);
		}
		emailValidation.setExpiryDate(new LocalDateTime().plusMinutes(globalSettings.getEmailExpireMinutes()).toDate());
		this.getBaseRepository().save(emailValidation);
		try {
			sendVerifyCode(emailValidation);
		} catch (Throwable e) {
			logger.error("send error", e);
		}
	}

	private void sendVerifyCode(EmailValidation emailValidation) {
		String email = emailValidation.getEmail();
		User user = userService.findByEmail(email);
		Map<String, Object> modal = Maps.newHashMap();
		modal.put("user", user);
		modal.put("email", email);
		modal.put("code", emailValidation.getCode());
		modal.put("emailExpireMinutes", globalSettings.getEmailExpireMinutes());
		emailService.asyncSendByTemplate(getEmailTemplateCode(emailValidation), email, modal);
	}

	private String getEmailTemplateCode(EmailValidation emailValidation) {
		return SYSTEM_EMAIL_VALIDATION_PREFIX + emailValidation.getType();
	}

	private String generateVerifyCode(String email, String type) {
		return UUID.randomUUID().toString().toUpperCase();
	}

}
